#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int set_interface_attribs(int fd, int speed) {
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr\n");
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= (CLOCAL | CREAD);    /* ignore modem controls */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */

    /* setup for non-canonical mode */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;

    tty.c_cc[VMIN]  = 0; /* read doesn't block */
    tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr\n");
        return -1;
    }
    return 0;
}

void set_blocking(int fd, int should_block) {
    struct termios tty;
    memset(&tty, 0, sizeof tty);
    if (tcgetattr(fd, &tty) != 0) {
        printf("Error from tggetattr\n");
        return;
    }

    tty.c_cc[VMIN]  = should_block ? 1 : 0;
    tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */

    if (tcsetattr(fd, TCSANOW, &tty) != 0)
        printf("Error from tcsetattr\n");
}

int main() {
    int fd;
    char *portname = "/dev/ttyS0"; /* change to your port */
    int speed = B9600; /* change to your baudrate */

    unsigned char buf[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
    // unsigned char buf[] ={0x01,0x03,0x00,0x01,0x00,0x01,0xD5,0xCA};

    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %m\n", portname);
        return -1;
    }

    set_interface_attribs(fd, speed);
    set_blocking(fd, 0); /* set no blocking */

    write(fd, buf, sizeof(buf)); /* send the data */
    sleep(1); /* wait for a second */

    unsigned char read_buf[1024];
    int n = read(fd, &read_buf, sizeof(read_buf)); /* read up to 1024 bytes from the serial port */
    if (n > 0) {
        printf("Received data: ");
        for (int i = 0; i < n; i++) {
            printf("%02X ", read_buf[i]);
        }
        printf("\n");
    } else if (n < 0) {
        printf("Error reading\n");
    } else {
        printf("No data received\n");
    }

    close(fd);
    return 0;
}


//编译：gcc -o run_com main_com.c